package com.carrental.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carrental.common.exception.BusinessException;
import com.carrental.crm.dto.CouponDTO;
import com.carrental.crm.entity.Coupon;
import com.carrental.crm.mapper.CouponMapper;
import com.carrental.crm.service.CouponService;
import com.carrental.crm.vo.CouponVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 优惠券服务实现类
 */
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createCoupon(CouponDTO couponDTO) {
        // 创建优惠券实体
        Coupon coupon = new Coupon();
        BeanUtils.copyProperties(couponDTO, coupon);
        
        // 设置默认值
        if (coupon.getStatus() == null) {
            coupon.setStatus(1); // 默认未发放状态
        }
        
        if (coupon.getUsedCount() == null) {
            coupon.setUsedCount(0); // 使用数量初始为0
        }
        
        coupon.setCreateTime(LocalDateTime.now());
        coupon.setUpdateTime(LocalDateTime.now());
        
        // 保存优惠券信息
        save(coupon);
        return coupon.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCoupon(CouponDTO couponDTO) {
        if (couponDTO.getId() == null) {
            throw new BusinessException("优惠券ID不能为空");
        }
        
        Coupon coupon = getById(couponDTO.getId());
        if (coupon == null) {
            throw new BusinessException("优惠券不存在");
        }
        
        // 已过期的优惠券不能修改
        if (coupon.getStatus() == 3) {
            throw new BusinessException("已过期的优惠券不能修改");
        }
        
        BeanUtils.copyProperties(couponDTO, coupon);
        
        // 检查有效期是否已过期
        LocalDateTime now = LocalDateTime.now();
        if (coupon.getEndTime().isBefore(now)) {
            coupon.setStatus(3); // 已过期
        }
        
        coupon.setUpdateTime(LocalDateTime.now());
        
        return updateById(coupon);
    }

    @Override
    public CouponVO getCouponById(Long id) {
        Coupon coupon = getById(id);
        if (coupon == null) {
            return null;
        }
        return convertToVO(coupon);
    }

    @Override
    public Page<CouponVO> pageCoupons(Page<Coupon> page, String name, Integer type, Integer status, String startTime, String endTime) {
        LambdaQueryWrapper<Coupon> queryWrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (StringUtils.isNotBlank(name)) {
            queryWrapper.like(Coupon::getName, name);
        }
        if (type != null) {
            queryWrapper.eq(Coupon::getType, type);
        }
        if (status != null) {
            queryWrapper.eq(Coupon::getStatus, status);
        }
        
        // 处理时间范围
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if (StringUtils.isNotBlank(startTime)) {
            LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
            queryWrapper.ge(Coupon::getCreateTime, startDateTime);
        }
        if (StringUtils.isNotBlank(endTime)) {
            LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
            queryWrapper.le(Coupon::getCreateTime, endDateTime);
        }
        
        // 按创建时间降序排序
        queryWrapper.orderByDesc(Coupon::getCreateTime);
        
        // 执行分页查询
        Page<Coupon> couponPage = page(page, queryWrapper);
        return convertToVOPage(couponPage);
    }

    @Override
    public List<CouponVO> getAvailableCoupons(Long vehicleId, Long storeId, Double amount) {
        LocalDateTime now = LocalDateTime.now();
        
        LambdaQueryWrapper<Coupon> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.le(Coupon::getStartTime, now)
                .ge(Coupon::getEndTime, now)
                .eq(Coupon::getStatus, 2) // 已发放
                .orderByDesc(Coupon::getCreateTime);
        
        List<Coupon> couponList = list(queryWrapper);
        
        // 过滤符合条件的优惠券
        List<CouponVO> availableCoupons = new ArrayList<>();
        for (Coupon coupon : couponList) {
            // 检查金额条件
            if (coupon.getThreshold() != null && amount < coupon.getThreshold().doubleValue()) {
                continue;
            }
            
            // 检查车型条件
            if (StringUtils.isNotBlank(coupon.getApplicableVehicles()) && vehicleId != null) {
                List<String> vehicleIds = Arrays.asList(coupon.getApplicableVehicles().split(","));
                if (!vehicleIds.contains(vehicleId.toString())) {
                    continue;
                }
            }
            
            // 检查门店条件
            if (StringUtils.isNotBlank(coupon.getApplicableStores()) && storeId != null) {
                List<String> storeIds = Arrays.asList(coupon.getApplicableStores().split(","));
                if (!storeIds.contains(storeId.toString())) {
                    continue;
                }
            }
            
            availableCoupons.add(convertToVO(coupon));
        }
        
        return availableCoupons;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCouponStatus(Long id, Integer status) {
        if (id == null || status == null) {
            throw new BusinessException("参数不能为空");
        }
        
        Coupon coupon = getById(id);
        if (coupon == null) {
            throw new BusinessException("优惠券不存在");
        }
        
        coupon.setStatus(status);
        coupon.setUpdateTime(LocalDateTime.now());
        
        return updateById(coupon);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean incrementIssueCount(Long id, Integer count) {
        if (id == null || count == null || count <= 0) {
            throw new BusinessException("参数不正确");
        }
        
        Coupon coupon = getById(id);
        if (coupon == null) {
            throw new BusinessException("优惠券不存在");
        }
        
        // 使用更新条件包装器直接更新数据库中的发放数量
        LambdaUpdateWrapper<Coupon> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Coupon::getId, id)
                .setSql("issue_count = issue_count + " + count)
                .set(Coupon::getStatus, 2) // 已发放
                .set(Coupon::getUpdateTime, LocalDateTime.now());
        
        return update(updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean incrementUsedCount(Long id) {
        if (id == null) {
            throw new BusinessException("优惠券ID不能为空");
        }
        
        Coupon coupon = getById(id);
        if (coupon == null) {
            throw new BusinessException("优惠券不存在");
        }
        
        // 使用更新条件包装器直接更新数据库中的使用数量
        LambdaUpdateWrapper<Coupon> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Coupon::getId, id)
                .setSql("used_count = used_count + 1")
                .set(Coupon::getUpdateTime, LocalDateTime.now());
        
        return update(updateWrapper);
    }

    /**
     * 将优惠券实体转换为VO
     *
     * @param coupon 优惠券实体
     * @return 优惠券VO
     */
    private CouponVO convertToVO(Coupon coupon) {
        if (coupon == null) {
            return null;
        }
        
        CouponVO vo = new CouponVO();
        BeanUtils.copyProperties(coupon, vo);
        
        // 设置类型名称
        if (coupon.getType() != null) {
            switch (coupon.getType()) {
                case 1:
                    vo.setTypeName("满减券");
                    break;
                case 2:
                    vo.setTypeName("折扣券");
                    break;
                case 3:
                    vo.setTypeName("直减券");
                    break;
                default:
                    vo.setTypeName("未知");
            }
        }
        
        // 设置状态名称
        if (coupon.getStatus() != null) {
            switch (coupon.getStatus()) {
                case 1:
                    vo.setStatusName("未发放");
                    break;
                case 2:
                    vo.setStatusName("已发放");
                    break;
                case 3:
                    vo.setStatusName("已过期");
                    break;
                default:
                    vo.setStatusName("未知");
            }
        }
        
        // 处理适用车型和门店名称（实际项目中可能需要调用其他服务获取名称）
        // 这里简单处理，实际项目中可能需要调用车辆服务和门店服务获取名称
        if (StringUtils.isNotBlank(coupon.getApplicableVehicles())) {
            vo.setApplicableVehicleNames("适用车型" + coupon.getApplicableVehicles());
        }
        
        if (StringUtils.isNotBlank(coupon.getApplicableStores())) {
            vo.setApplicableStoreNames("适用门店" + coupon.getApplicableStores());
        }
        
        return vo;
    }

    /**
     * 将优惠券分页数据转换为VO分页
     *
     * @param page 优惠券分页
     * @return 优惠券VO分页
     */
    private Page<CouponVO> convertToVOPage(Page<Coupon> page) {
        Page<CouponVO> voPage = new Page<>();
        BeanUtils.copyProperties(page, voPage, "records");
        
        List<CouponVO> voList = new ArrayList<>();
        for (Coupon coupon : page.getRecords()) {
            voList.add(convertToVO(coupon));
        }
        voPage.setRecords(voList);
        
        return voPage;
    }
} 